#include <windows.h>
#include <stdio.h>
#include <stdio.h>

#include "lib.h"
#include "npipe.h"

int32 gKind = -1;

class Client : public NamedPipe
{
	public:
		Client() : NamedPipe(1024) { }

		void ioerror() { printf("IOError!\n"); }
		void recvd(uint8* Msg, int32 Len) 
		{
			putchar('\n');

			if (gKind == 0 && Msg[1] == 'S')
			{
				int32 num, len;

				num = Msg[3];
				Msg += Msg[0];

				while (num-- > 0)
				{
					++Msg;
					if (*Msg++ == 'E')
					{
						putchar('E');
						putchar(*Msg++);
						putchar(*Msg++);
						putchar('\n');
						break;
					}
#ifdef ADMLIST_SENTALL
					len = *Msg++;
					printf("Name: [");
					while (len-- > 0)
						putchar(*Msg++);
					len = (int32)
						((((int32)Msg[3]) & 0xff) |
						((((int32)Msg[2]) << 8) & 0xff00) |
						((((int32)Msg[1]) << 16) & 0xff0000) |
						((((int32)Msg[0]) << 24) & 0xff000000));
					printf("]  Version: 0x%08x  Zip: [", len);
					Msg += 4;
#else
					printf("Zip: [", len);
#endif
					len = *Msg++;
					while (len-- > 0)
						putchar(*Msg++);
					printf("]\n");
				}
			}
			else
			{
				while (Len-- > 0)
					putchar(*Msg++);
				putchar('\n');
			}
			gKind = -1;
		}

	protected:
		int32 kind;
};

int
main(int argc, char* argv[])
{
	Client c;
	uint8 buf[256], buf2[256];
	int32 len, len2, major, minor, ver, index;
	bool8 active = true;

	if (!c.open("\\\\.\\pipe\\pixpatch"))
	{
		printf("open failed\n");
		return -1;
	}

	while (active)
	{
		printf("\n[A]dd, [R]emove, [U]date, [L|l]ist, [P]assword, [q]uit> ");
		buf[0] = '\0';
		gets((char*)buf);
		switch (buf[0])
		{
			case 'A':
				len = 2;
				printf("Name: ");
				gets((char*)buf + len + 1);
				len2 = strlen((char*)buf + len + 1);
				buf[len] = (uint8)(len2 & 0xff);
				len += len2 + 1;
				printf("Version (d.d): ");
				gets((char*)buf2);
				major = minor = 0;
				sscanf((char*)buf2, "%ld.%ld", &major, &minor);
				ver = ((major & 0xffff) << 16) | (minor & 0xffff);
				buf[len++] = (uint8)((ver>>24)&0xff);
				buf[len++] = (uint8)((ver>>16)&0xff);
				buf[len++] = (uint8)((ver>>8)&0xff);
				buf[len++] = (uint8)(ver&0xff);
				printf("Zipname: ");
				gets((char*)buf + len + 1);
				len2 = strlen((char*)buf + len + 1);
				buf[len] = (uint8)(len2 & 0xff);
				len += len2 + 1;
				buf[0] = (uint8)(len & 0xff);
				buf[1] = 'A';
				break;
			case 'R':
				printf("Remove index: ");
				gets((char*)buf2);
				sscanf((char*)buf2, "%ld", &index);
				len = 3;
				buf[0] = (uint8)(len & 0xff);
				buf[1] = 'R';
				buf[2] = (uint8)(index & 0xff);
				break;
			case 'U':
				len = 2;
				printf("Update index: ");
				gets((char*)buf2);
				sscanf((char*)buf2, "%ld", &index);
				buf[len++] = (uint8)(index & 0xff);
				printf("Name: ");
				gets((char*)buf + len + 1);
				len2 = strlen((char*)buf + len + 1);
				buf[len] = (uint8)(len2 & 0xff);
				len += len2 + 1;
				printf("Version (d.d): ");
				gets((char*)buf2);
				major = minor = 0;
				sscanf((char*)buf2, "%ld.%ld", &major, &minor);
				ver = ((major & 0xffff) << 16) | (minor & 0xffff);
				buf[len++] = (uint8)((ver>>24)&0xff);
				buf[len++] = (uint8)((ver>>16)&0xff);
				buf[len++] = (uint8)((ver>>8)&0xff);
				buf[len++] = (uint8)(ver&0xff);
				printf("Zipname: ");
				gets((char*)buf + len + 1);
				len2 = strlen((char*)buf + len + 1);
				buf[len] = (uint8)(len2 & 0xff);
				len += len2 + 1;
				buf[0] = (uint8)(len & 0xff);
				buf[1] = 'U';
				break;
			case 'L':
			case 'l':
				len = 2;
				buf[1] = buf[0];
				buf[0] = (uint8)len;
				gKind = 0;
				break;
			case 'P':
				len = 2;
				buf[0] = (uint8)len;
				buf[1] = 'P';
				break;
			case 'q':
				active = false;
				continue;

			default:
				printf("(Sending as-is)");
				len = strlen((char*)buf) + 1;
				MoveMemory(buf + 1, buf, len);
				buf[0] = (uint8)(len & 0xff);
				break;
		}

		if (!c.send(buf, len))
		{
			printf("***Failed writing to pipe.\n");
			return -1;
		}

		printf("Waiting for result...");
		if (WAIT_IO_COMPLETION != SleepEx(INFINITE, TRUE))
			printf("Read timeout\n");
	}

	return 0;
}
